home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / v10n06.arc / BOUNCE.ARC / BOUNCE.C next >
C/C++ Source or Header  |  1991-03-06  |  8KB  |  253 lines

  1. /*-----------------------------------------------------------------
  2.    BOUNCE.C -- Palette Animation Using Windows 3.0 Palette Manager
  3.                (c) Charles Petzold, 1990
  4.   -----------------------------------------------------------------*/
  5.  
  6. #include <windows.h>
  7.  
  8. long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;
  9.  
  10. #define ID_TIMER    1
  11.  
  12. int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
  13.                     LPSTR lpszCmdLine, int nCmdShow)
  14.      {
  15.      char     szAppName [] = "Bounce" ;
  16.      HWND     hwnd ;
  17.      MSG      msg ;
  18.      WNDCLASS wndclass ;
  19.  
  20.      if (!hPrevInstance) 
  21.           {
  22.           wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  23.           wndclass.lpfnWndProc   = WndProc ;
  24.           wndclass.cbClsExtra    = 0 ;
  25.           wndclass.cbWndExtra    = 0 ;
  26.           wndclass.hInstance     = hInstance ;
  27.           wndclass.hIcon         = NULL ;
  28.           wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  29.           wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
  30.           wndclass.lpszMenuName  = szAppName ;
  31.           wndclass.lpszClassName = szAppName ;
  32.  
  33.           RegisterClass (&wndclass) ;
  34.           }
  35.  
  36.      hwnd = CreateWindow (szAppName, "Bounce: Palette Animation",
  37.                           WS_OVERLAPPEDWINDOW,
  38.                           CW_USEDEFAULT, CW_USEDEFAULT,
  39.                           CW_USEDEFAULT, CW_USEDEFAULT,
  40.                           NULL, NULL, hInstance, NULL) ;
  41.  
  42.      ShowWindow (hwnd, nCmdShow) ;
  43.      UpdateWindow (hwnd) ;
  44.  
  45.      while (GetMessage (&msg, NULL, 0, 0))
  46.           {
  47.           TranslateMessage (&msg) ;
  48.           DispatchMessage (&msg) ;
  49.           }
  50.  
  51.      return msg.wParam ;
  52.      }
  53.  
  54. long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  55.      {
  56.      static BOOL        bLeftToRight = TRUE ;
  57.      static HPALETTE    hPal ;
  58.      static LOCALHANDLE hLocalMem ;
  59.      static LOGPALETTE  *plp ;
  60.      static short       cxClient, cyClient, iBall = 0 ;
  61.      BOOL               bPalSupport ;
  62.      HBRUSH             hBrush ;
  63.      HDC                hdc ;
  64.      int                x1, x2, y1, y2 ;
  65.      long               i ;
  66.      PAINTSTRUCT        ps ;
  67.      RECT               rc ;
  68.  
  69.      switch (message)
  70.           {
  71.           case WM_CREATE:
  72.  
  73.                     // Check for palette support
  74.  
  75.                hdc = GetDC (hwnd) ;
  76.  
  77.                bPalSupport = (RC_PALETTE & GetDeviceCaps (hdc, RASTERCAPS)) &&
  78.                              (GetDeviceCaps (hdc, SIZEPALETTE) -
  79.                               GetDeviceCaps (hdc, NUMRESERVED) > 34) ;
  80.  
  81.                ReleaseDC (hwnd, hdc) ;
  82.  
  83.                if (!bPalSupport)
  84.                     {
  85.                     MessageBox (hwnd, "Program requires palette support",
  86.                                 "Bounce", MB_ICONEXCLAMATION | MB_OK) ;
  87.  
  88.                     DestroyWindow (hwnd) ;
  89.                     return 0 ;
  90.                     }
  91.  
  92.                     // Allocate memory for LOGPALETTE structure and lock it
  93.  
  94.                hLocalMem = LocalAlloc (LMEM_MOVEABLE, sizeof (LOGPALETTE) +
  95.                                                  33 * sizeof (PALETTEENTRY)) ;
  96.  
  97.                plp = (LOGPALETTE *) LocalLock (hLocalMem) ;
  98.  
  99.                     // Initialize the fields of the LOGPALETTE structure
  100.  
  101.                plp->palVersion    = 0x300 ;
  102.                plp->palNumEntries = 34 ;
  103.  
  104.                for (i = 0 ; i < 34 ; i++)
  105.                     {
  106.                     plp->palPalEntry[i].peRed   = 255 ;
  107.                     plp->palPalEntry[i].peGreen = (i ==  0 ? 0 : 255) ;
  108.                     plp->palPalEntry[i].peBlue  = (i ==  0 ? 0 : 255) ;
  109.                     plp->palPalEntry[i].peFlags = (i == 33 ? 0 : PC_RESERVED) ;
  110.                     }
  111.  
  112.                     // Create the logical palette & unlock the memory block
  113.  
  114.                hPal = CreatePalette (plp) ;
  115.                LocalUnlock (hLocalMem) ;
  116.  
  117.                     // Set the timer for 50 msec
  118.  
  119.                SetTimer (hwnd, ID_TIMER, 50, NULL) ;
  120.                return 0 ;
  121.  
  122.           case WM_SIZE:
  123.                cxClient = LOWORD (lParam) ;
  124.                cyClient = HIWORD (lParam) ;
  125.                return 0 ;
  126.  
  127.           case WM_TIMER:
  128.                plp = (LOGPALETTE *) LocalLock (hLocalMem) ;
  129.  
  130.                     // Set old ball color to white
  131.  
  132.                plp->palPalEntry[iBall].peGreen = 255 ;
  133.                plp->palPalEntry[iBall].peBlue  = 255 ;
  134.  
  135.                iBall += (bLeftToRight ? 1 : -1) ;
  136.  
  137.                if (iBall == (bLeftToRight ? 33 : -1))
  138.                     {
  139.                     iBall = (bLeftToRight ? 31 : 1) ;
  140.                     bLeftToRight ^= TRUE ;
  141.                     }
  142.  
  143.                     // Set new ball color to red
  144.  
  145.                plp->palPalEntry[iBall].peGreen = 0 ;
  146.                plp->palPalEntry[iBall].peBlue  = 0 ;
  147.  
  148.                     // Animate the palette
  149.  
  150.                AnimatePalette (hPal, 0, 33, plp->palPalEntry) ;
  151.  
  152.                LocalUnlock (hLocalMem) ;
  153.                return 0 ;
  154.  
  155.           case WM_PAINT:
  156.                hdc = BeginPaint (hwnd, &ps) ;
  157.  
  158.                SelectPalette (hdc, hPal, FALSE) ;
  159.                RealizePalette (hdc) ;
  160.  
  161.                     // Draw window background using palette index 33
  162.  
  163.                GetWindowRect (hwnd, &rc) ;
  164.                hBrush = CreateSolidBrush (PALETTEINDEX (33)) ;
  165.                FillRect (hdc, &rc, hBrush) ;
  166.                DeleteObject (hBrush) ;
  167.  
  168.                SelectObject (hdc, GetStockObject (NULL_PEN)) ;
  169.  
  170.                     // Draw the 33 balls
  171.  
  172.                for (i = 0 ; i < 33 ; i++)
  173.                     {
  174.                     x1 =  i      * cxClient / 33 ;
  175.                     x2 = (i + 1) * cxClient / 33 ;
  176.  
  177.                     if (i < 9)
  178.                          {
  179.                          y1 =  i      * cyClient / 9 ;
  180.                          y2 = (i + 1) * cyClient / 9 ;
  181.                          }
  182.                     else if (i < 17)
  183.                          {
  184.                          y1 = (16 - i) * cyClient / 9 ;
  185.                          y2 = (17 - i) * cyClient / 9 ;
  186.                          }
  187.                     else if (i < 25)
  188.                          {
  189.                          y1 = (i - 16) * cyClient / 9 ;
  190.                          y2 = (i - 15) * cyClient / 9 ;
  191.                          }
  192.                     else
  193.                          {
  194.                          y1 = (32 - i) * cyClient / 9 ;
  195.                          y2 = (33 - i) * cyClient / 9 ;
  196.                          }
  197.  
  198.                     hBrush = CreateSolidBrush (PALETTEINDEX (i)) ;
  199.                     SelectObject (hdc, hBrush) ;
  200.  
  201.                     Ellipse (hdc, x1, y1, x2, y2) ;
  202.  
  203.                     DeleteObject (SelectObject (hdc,
  204.                                   GetStockObject (BLACK_BRUSH))) ;
  205.                     }
  206.  
  207.                EndPaint (hwnd, &ps) ;
  208.                return 0 ;
  209.  
  210.           case WM_QUERYNEWPALETTE:
  211.                hdc = GetDC (hwnd) ;
  212.  
  213.                SelectPalette (hdc, hPal, FALSE) ;
  214.  
  215.                if (RealizePalette (hdc) > 0)
  216.                     {
  217.                     ReleaseDC (hwnd, hdc) ;
  218.                     InvalidateRect (hwnd, NULL, FALSE) ;
  219.                     return TRUE ;
  220.                     }
  221.                else
  222.                     {
  223.                     ReleaseDC (hwnd, hdc) ;
  224.                     return FALSE ;
  225.                     }
  226.                break ;
  227.  
  228.           case WM_PALETTECHANGED:
  229.                if (wParam != hwnd)
  230.                     {
  231.                     hdc = GetDC (hwnd) ;
  232.  
  233.                     SelectPalette (hdc, hPal, FALSE) ;
  234.  
  235.                     if (RealizePalette (hdc) > 0)
  236.                          {
  237.                          InvalidateRect (hwnd, NULL, FALSE) ;
  238.                          }
  239.  
  240.                     ReleaseDC (hwnd, hdc) ;
  241.                     }
  242.                return 0 ;
  243.  
  244.           case WM_DESTROY :
  245.                KillTimer (hwnd, ID_TIMER) ;
  246.                LocalFree (hLocalMem) ;
  247.                DeleteObject (hPal) ;
  248.                PostQuitMessage (0) ;
  249.                return 0 ;
  250.           }
  251.      return DefWindowProc (hwnd, message, wParam, lParam) ;
  252.      }
  253.